package com.luoying.itew.service;

import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import android.widget.RemoteViews;

import androidx.core.app.NotificationCompat;
import androidx.core.content.FileProvider;

import com.luoying.itew.R;
import com.luoying.itew.util.LogUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;



/**
 * Created by asus on 2017/8/20.
 */

public class MyIntentService extends IntentService{
    public static final String TAG = "MyIntentService";
    private static final String ACTION_UPDATE = "com.luoying.itew.service.action.update";
    private static final String EXTRA_URL = "com.luoying.itew.service.extra.url";
    private static final String EXTRA_FILE_NAME = "com.luoying.itew.service.extra.file.signAddress";
    private static final String CHANNEL_ID = "100001";
    private boolean isRunning = false;
    private NotificationManager notificationManager;
    private Notification updateNotification;
    private PendingIntent updatePendingIntent;
    private static OnProgressListener mProgressListener;

    public interface OnProgressListener {
        void onProgress(long progress);

        void onSuccess(boolean isSuccess);
    }

    public MyIntentService() {
        super("AppUpdateService");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID,getPackageName(),NotificationManager.IMPORTANCE_LOW);
            notificationManager.createNotificationChannel(channel);
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this,CHANNEL_ID);
            startForeground(1, builder.build());
        }
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            final String action = intent.getAction();
            if (ACTION_UPDATE.equals(action)) {
                final String param1 = intent.getStringExtra(EXTRA_URL);
                final String param2 = intent.getStringExtra(EXTRA_FILE_NAME);
                LogUtils.d(TAG,"-------- startDownloade ------");
                startDownloade(param1, param2);
            }
        }
    }

    @Override
    public void onDestroy() {
        mProgressListener = null;
        super.onDestroy();
    }

    public static void startUpdate(Context context, String param1, String param2, OnProgressListener pregressListener) {
        mProgressListener = pregressListener;
        Intent intent = new Intent(context, MyIntentService.class);
        intent.setAction(ACTION_UPDATE);
        intent.putExtra(EXTRA_URL, param1);
        intent.putExtra(EXTRA_FILE_NAME, param2);
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
            context.startForegroundService(intent);
        }else {
            context.startService(intent);
        }
        LogUtils.d(TAG,"-------- startService ------");
    }

    private void startDownloade(String url, String fileName) {
        if (isRunning) {
            return;
        }
        isRunning = true;
        initRemoteView();

        try {
            boolean isSuccess = downloadUpdateFile(url, fileName);
            if (mProgressListener != null) {
                mProgressListener.onSuccess(isSuccess);
            }
            if (isSuccess) {
                install(this,fileName);
                try {
                    notificationManager.cancel(0);
                } catch (Exception ex) {
                }
            } else {
                if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
                    NotificationChannel channel = new NotificationChannel(CHANNEL_ID,getPackageName(),NotificationManager.IMPORTANCE_DEFAULT);
                    notificationManager.createNotificationChannel(channel);
                }
                NotificationCompat.Builder notificationCompat = new NotificationCompat.Builder(this,CHANNEL_ID)
                        .setContentTitle(getString(R.string.app_name))
                        .setContentText("下载失败")
                        .setSmallIcon(R.mipmap.antai);
                notificationManager.notify(0, notificationCompat.build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 通过隐式意图调用系统安装程序安装APK
     */
    public static void install(Context context,String fileName) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        // 由于没有在Activity环境下启动Activity,设置下面的标签
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N) { //判读版本是否在7.0以上
            //参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致   参数3  共享的文件
            Uri apkUri = FileProvider.getUriForFile(context, "com.luoying.itew.fileprovider", new File(fileName));
            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        }else{
            intent.setDataAndType(Uri.fromFile(new File(fileName)),"application/vnd.android.package-archive");
        }
        context.startActivity(intent);
    }

    /**
     * 初始化状态栏进度条
     */
    private void initRemoteView() {
        try {
            if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
                NotificationChannel channel = new NotificationChannel(CHANNEL_ID,getPackageName(),NotificationManager.IMPORTANCE_LOW);
                notificationManager.createNotificationChannel(channel);
            }
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this,CHANNEL_ID)
                    .setTicker("版本更新下载")
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.mipmap.antai);
            updatePendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, RemoteViews.class), 0);
            builder.setContentIntent(updatePendingIntent);
            //状态栏提醒内容
            RemoteViews remoteViews = new RemoteViews(getApplication().getPackageName(), R.layout.progress);
            remoteViews.setProgressBar(R.id.progressBar1, 100, 0, false);
            remoteViews.setTextViewText(R.id.textView1, "0%");
            builder.setCustomContentView(remoteViews);
            updateNotification = builder.build();
            // 发出通知
            notificationManager.notify(0, updateNotification);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 下载文件
     *
     * @param downloadUrl
     * @param filepath
     * @return
     * @throws Exception
     */
    private boolean downloadUpdateFile(String downloadUrl, String filepath) {
        try {
            int downloadCount = 0;
            int currentSize = 0;
            long totalSize = 0;
            int updateTotalSize = 0;
            boolean result = false;
            HttpURLConnection httpConnection = null;
            InputStream is = null;
            FileOutputStream fos = null;
            File temp = new File(filepath + ".tmp");
            if (temp.getParentFile().isDirectory()) {
                temp.getParentFile().mkdirs();
            }
            try {
                LogUtils.d(TAG,"URL == " + downloadUrl);
                URL url = new URL(downloadUrl);
                httpConnection = (HttpURLConnection) url.openConnection();
                httpConnection.setRequestProperty("User-Agent", "PacificHttpClient");
                if (currentSize > 0) {
                    httpConnection.setRequestProperty("RANGE", "bytes=" + currentSize + "-");
                }
                httpConnection.setConnectTimeout(20000);
                httpConnection.setReadTimeout(120000);
                updateTotalSize = httpConnection.getContentLength();
                if (httpConnection.getResponseCode() == 404) {
                    throw new Exception("fail!");
                }
                is = httpConnection.getInputStream();
                fos = new FileOutputStream(temp, false);
                byte buffer[] = new byte[4096];
                int readsize = 0;
                while ((readsize = is.read(buffer)) > 0) {
                    fos.write(buffer, 0, readsize);
                    totalSize += readsize; // 为了防止频繁的通知导致应用吃紧，百分比增加10才通知一次
                    if ((downloadCount == 0) || (int) (totalSize * 100 / updateTotalSize) - 1 > downloadCount) {
                        downloadCount += 1;
                        try {
                            updateNotification.contentView.setProgressBar(R.id.progressBar1, 100,
                                    (int) totalSize * 100 / updateTotalSize, false);
                            updateNotification.contentView.setTextViewText(R.id.textView1, (int) totalSize * 100 / updateTotalSize + "%");
                            notificationManager.notify(0, updateNotification);
                            if (mProgressListener != null) {
                                mProgressListener.onProgress( totalSize * 100 / updateTotalSize);
                            }
                        } catch (Exception ex) {
                            Log.d(ex.getMessage(), ex.toString());
                        }
                    }
                }
                temp.renameTo(new File(filepath));
                temp.delete();
            } finally {
                if (httpConnection != null) {
                    httpConnection.disconnect();
                }
                if (is != null) {
                    is.close();
                }
                if (fos != null) {
                    fos.close();
                }
                result = updateTotalSize > 0 && updateTotalSize == totalSize;
                if (!result) { //下载失败或者为下载完成
                    new File(filepath).delete();
                }
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


}
